package com.atguigu.tingshu.album.service.impl;
import java.util.Date;

import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.common.result.Result;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.user.client.UserInfoFeignClient;
import com.atguigu.tingshu.vo.album.*;
import com.google.common.collect.Maps;

import com.atguigu.tingshu.album.config.VodConstantProperties;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.mapper.TrackStatMapper;
import com.atguigu.tingshu.album.service.TrackInfoService;
import com.atguigu.tingshu.album.service.VodService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.common.util.UploadFileUtil;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.TrackInfo;
import com.atguigu.tingshu.model.album.TrackStat;
import com.atguigu.tingshu.query.album.TrackInfoQuery;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcloud.vod.VodUploadClient;
import com.qcloud.vod.model.VodUploadRequest;
import com.qcloud.vod.model.VodUploadResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.bouncycastle.crypto.tls.ConnectionEnd.client;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class TrackInfoServiceImpl extends ServiceImpl<TrackInfoMapper, TrackInfo> implements TrackInfoService {

	@Autowired
	private TrackInfoMapper trackInfoMapper;
	@Autowired
	private VodService vodService;
    @Autowired
    private TrackStatMapper trackStatMapper;
    @Autowired
    private AlbumInfoMapper albumInfoMapper;
	@Autowired
	private UserInfoFeignClient userInfoFeignClient;
	@Autowired
	private AlbumStatMapper albumStatMapper;
	@Override
	public UploadTrackVo uploadTrack(MultipartFile file) {
		return vodService.uploadTrack(file);
	}

	@Transactional
	@Override
	public void saveTrackInfo(TrackInfoVo trackInfoVo) {
		//获取当前登录用户的id
		Long userId = AuthContextHolder.getUserId();
		//1.保存声音基本信息
		TrackInfo trackInfo = new TrackInfo();
		BeanUtils.copyProperties(trackInfoVo,trackInfo);
		trackInfo.setSource(SystemConstant.TRACK_SOURCE_UPLOAD);//声音源
		trackInfo.setStatus(SystemConstant.TRACK_STATUS_PASS);//声音审核状态
		trackInfo.setUserId(userId);//声音的用户id
		/**
		 * 根据专辑的id从声音的基本信息表中获取声音的列表数据（需要根据order_num进行倒序排序）
		 * 判断列表数据是否为空：
		 * 1.若为空，orderNUm=1
		 * 2.若不为空，从声音列表集合中获取第一个声音基本信息对象，获取到orderNum的值，对orderNum进行++
		 */
		LambdaQueryWrapper<TrackInfo> lambdaQueryWrapper= new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(TrackInfo::getAlbumId,trackInfoVo.getAlbumId());
		lambdaQueryWrapper.orderByDesc(TrackInfo::getOrderNum);
		lambdaQueryWrapper.last("limit 1");

		TrackInfo dbtrackInfo = trackInfoMapper.selectOne(lambdaQueryWrapper);
		if (dbtrackInfo==null){
			trackInfo.setOrderNum(1);
		}else {
			Integer orderNum = dbtrackInfo.getOrderNum();
			orderNum++;
			trackInfo.setOrderNum(orderNum);
		}
		//调用腾讯云点播接口获取媒体相关数据
		TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(trackInfoVo.getMediaFileId());
		trackInfo.setMediaSize(trackMediaInfoVo.getSize());
		trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
		trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
		trackInfo.setMediaType(trackMediaInfoVo.getType());
		trackInfoMapper.insert(trackInfo);
		//2.初始化声音统计数据
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PLAY);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COLLECT);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_PRAISE);
		this.saveTrackStat(trackInfo.getId(),SystemConstant.TRACK_STAT_COMMENT);
		//3.修改专辑基本信息表中的include_track_count字段值
		AlbumInfo albumInfo = albumInfoMapper.selectById(trackInfoVo.getAlbumId());
		Integer includeTrackCount = albumInfo.getIncludeTrackCount();
		includeTrackCount++;
		albumInfo.setIncludeTrackCount(includeTrackCount);
		albumInfoMapper.updateById(albumInfo);
	}

	@Override
	public IPage<TrackListVo> findUserTrackPage(Integer pageNum, Integer pageSize, TrackInfoQuery trackInfoQuery) {
		//进行条件分页查询
		Long userId = AuthContextHolder.getUserId();
		trackInfoQuery.setUserId(userId);
		//创建分页
		Page<TrackListVo> page = new Page<>(pageNum,pageSize);
		IPage<TrackListVo> trackListVoIPage = trackInfoMapper.findUserTrackPage(page,trackInfoQuery);
		return trackListVoIPage;
	}
	@Override
	public void updateTrackInfo(Integer id, TrackInfoVo trackinfoVo) {
		//1.根据id查询声音的基本信息
		TrackInfo trackInfo = trackInfoMapper.selectById(id);

		/**
		 * 判断用户是否上传了声音，如果是就需要根据新的媒体文件id查询媒体信息，然后修改媒体信息
		 */
		String dbmediaFileId = trackInfo.getMediaFileId();
		String mediaFileId = trackinfoVo.getMediaFileId();
		if (!dbmediaFileId.equals(mediaFileId)){
			//调用腾讯云点播服务接口获取媒体相关数据
			TrackMediaInfoVo trackMediaInfoVo = vodService.getMediaInfo(mediaFileId);
			trackInfo.setMediaDuration(new BigDecimal(trackMediaInfoVo.getDuration()));
			trackInfo.setMediaUrl(trackMediaInfoVo.getMediaUrl());
			trackInfo.setMediaSize(trackMediaInfoVo.getSize());
			trackInfo.setMediaType(trackMediaInfoVo.getType());
		}

		BeanUtils.copyProperties(trackinfoVo,trackInfo);
		trackInfoMapper.updateById(trackInfo);
	}

	@Transactional
	@Override
	public void removeTrackInfo(Integer id) {
		//根据声音id查询声音数据
		TrackInfo trackInfo = trackInfoMapper.selectById(id);
		//1.根据声音的id删除声音基本数据
		trackInfoMapper.deleteById(id);
		//2.根据声音的id删除声音统计数据
		LambdaQueryWrapper<TrackStat> lambdaQueryWrapper=new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(TrackStat::getTrackId,id);
		trackStatMapper.delete(lambdaQueryWrapper);
		//3.修改专辑基本信息中的include_track_count字段值
		Long albumId = trackInfo.getAlbumId();
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		Integer includeTrackCount = albumInfo.getIncludeTrackCount();
		includeTrackCount--;
		albumInfo.setIncludeTrackCount(includeTrackCount);
		albumInfoMapper.updateById(albumInfo);
		//4.调用腾讯云点播服务接口删除媒体文件信息
		vodService.removeMediaFile(trackInfo.getMediaFileId());
	}

	@Override
	public IPage<AlbumTrackListVo> findAlbumTrackPage(Long albumId, Long page, Long limit) {
		//根据专辑id查询专辑数据
		AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
		String payType = albumInfo.getPayType();
		//分页查询专辑的声音列表
		IPage<AlbumTrackListVo> trackListVoPage = new Page<>(page,limit);
		trackInfoMapper.findAlbumTrackPage(trackListVoPage,albumId);

		List<AlbumTrackListVo> records = trackListVoPage.getRecords();	//获取当前页的声音列表数据
		Long userId = AuthContextHolder.getUserId();	//获取当前登录用户id
		if(userId==null){			//用户未登录
			//判断专辑付费类型
			if (!SystemConstant.ALBUM_PAY_TYPE_FREE.equals(payType)){
				Integer tracksForFree = albumInfo.getTracksForFree();  //获取试听声音数
				records.stream().filter(albumTrackListVo ->
					albumTrackListVo.getOrderNum()>tracksForFree
				).forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
			}
		}else {		//用户已经登录
			//判断是否是vip免费专辑
			if(SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType)){		//vip免费
				//判断当前用户登录的身份
				Result<UserInfo> userInfoResult = userInfoFeignClient.getUserInfoVo(userId);
				UserInfo userInfo = userInfoResult.getData();
				if(userInfo.getIsVip().intValue() == 1) {     // 是vip用户

					// 判断vip是否过期
					Date vipExpireTime = userInfo.getVipExpireTime();
					if (vipExpireTime.before(new Date())) {   // vip过期了
						Integer tracksForFree = albumInfo.getTracksForFree();        // 获取试听的声音数
						records.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
								.forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
					}
				}else {		//  非vip用户
						Integer tracksForFree = albumInfo.getTracksForFree();		// 获取试听的声音数
						records.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
								.forEach(albumTrackListVo -> albumTrackListVo.setIsShowPaidMark(true));
					}


				}else  if(SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)) {		// 付费专辑

				/**
				 * 根据用户的购买情况，构建isShowPaidMark：
				 * 1、如果用户购买过该专辑，把非试听声音isShowPaidMark的值设置为false
				 * 2、如果用户未购买过该专辑，但是购买过某一个声音，那么就应该把这个声音isShowPaidMark的值设置为false
				 *
				 * 用户购买的声音或者专辑信息是在哪一张表中记录了？
				 * 1、user_paid_album记录了专辑的购买信息
				 * 2、user_paid_track记录了声音的购买信息
				 */
				Integer tracksForFree = albumInfo.getTracksForFree();		// 获取试听的声音数
				List<Long> noFreeTrackIds = records.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
						.map(albumTrackListVo -> albumTrackListVo.getTrackId()).collect(Collectors.toList());

				// 远程调用user微服务的接口，判断noFreeTrackIds中的声音是否购买过
				//  Map键表示是的就是声音的id ， Map的值表示是否购买过： 0表示未购买过   1表示购买过
				Result<Map<Long , Integer>> isPaidTrackResult =  userInfoFeignClient.userIsPaidTrack(albumId , noFreeTrackIds);   // 8 ， 9 ， 10 ， 11
				Map<Long, Integer> trackResulData = isPaidTrackResult.getData();
				records.stream().filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
						.forEach(albumTrackListVo -> {
							Long trackId = albumTrackListVo.getTrackId();
							int isPaid = trackResulData.get(trackId);
							boolean isShowPaidMark =  !(isPaid == 1) ;
							albumTrackListVo.setIsShowPaidMark(isShowPaidMark);
						});

			}

		}
		//
		return trackListVoPage;
	}

	@Override
	public void updateTrackStat(TrackStatMqVo trackStatMqVo) {
		//更新track_stat表中的数据值和album_stat表中的数据
		//根据声音id和stat_type进行数据查询
		LambdaQueryWrapper<TrackStat> trackStatLambdaQueryWrapper = new LambdaQueryWrapper<>();
		trackStatLambdaQueryWrapper.eq(TrackStat::getTrackId,trackStatMqVo.getTrackId());
		trackStatLambdaQueryWrapper.eq(TrackStat::getStatType,trackStatMqVo.getStatType());
		TrackStat trackStat = trackStatMapper.selectOne(trackStatLambdaQueryWrapper);
		trackStat.setStatNum(trackStat.getStatNum()+trackStatMqVo.getCount());
		trackStatMapper.updateById(trackStat);
		//更新album_stat表中的数据
		LambdaQueryWrapper<AlbumStat> albumStatLambdaQueryWrapper = new LambdaQueryWrapper<>();
		albumStatLambdaQueryWrapper.eq(AlbumStat::getAlbumId,trackStatMqVo.getAlbumId());
		switch (trackStatMqVo.getStatType()){
			case SystemConstant.TRACK_STAT_PLAY:
				albumStatLambdaQueryWrapper.eq(AlbumStat::getStatType,SystemConstant.ALBUM_STAT_PLAY);
				break;
			case SystemConstant.TRACK_STAT_COLLECT:
				albumStatLambdaQueryWrapper.eq(AlbumStat::getStatType,SystemConstant.ALBUM_STAT_SUBSCRIBE);
				break;
			case SystemConstant.TRACK_STAT_PRAISE:
				albumStatLambdaQueryWrapper.eq(AlbumStat::getStatType,SystemConstant.ALBUM_STAT_BROWSE);
				break;
			case SystemConstant.TRACK_STAT_COMMENT:
				albumStatLambdaQueryWrapper.eq(AlbumStat::getStatType,SystemConstant.ALBUM_STAT_COMMENT);
				break;
		}
		AlbumStat albumStat = albumStatMapper.selectOne(albumStatLambdaQueryWrapper);
		albumStat.setStatNum(albumStat.getStatNum()+trackStatMqVo.getCount());
		albumStatMapper.updateById(albumStat);
	}

	@Override
	public TrackStatVo getTrackStatVo(Long trackId) {
		return trackStatMapper.getTrackStatVo(trackId);
	}

	private void saveTrackStat(Long trackId, String statType) {
		TrackStat trackStat = new TrackStat();
		trackStat.setTrackId(trackId);
		trackStat.setStatType(statType);
		trackStat.setStatNum(0);
		trackStatMapper.insert(trackStat);
	}
}
